/**
 * @class   wosh::WoshModule
 * @brief   Interface of a generic CoreModule. Such modules are embedded into
 *          the kernel itself.
 * @see     \ref CoreModules
 ****************************************************************************
 * \defgroup CoreModules Core-Modules
 *
 * Core modules are low-level services embedded into wosh::WoshKernel.
 * They implement wosh::WoshModule interface.
 *
 * Once WoshKernel has been allocated (usually within main entry point),
 * WOSH components may access to core-modules as shown in following snippet:
 * \code
WoshHost* localHost = WoshKernel::getInstance()->network().getLocalWoshHost();
 * \endcode
 *
 * For convenience, some modules provide static methods, such as:
 * \code
bool found = UserManager::isUser(username);
 * \endcode
 *
 *
 * @see     wosh::WoshModule
 ****************************************************************************
 * @version 0.8.384 $Id: WoshModule.h 2739 2010-07-07 16:29:01Z alex $
 * @author  Alessandro Polo
 ****************************************************************************/
/* Copyright (c) 2007-2010, WOSH - Wide Open Smart Home 
 * by Alessandro Polo - OpenSmartHome.com
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of the OpenSmartHome.com WOSH nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY Alessandro Polo ''AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL Alessandro Polo BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 ****************************************************************************/

#ifndef __WOSH_Core_WoshModule_H__
 #define __WOSH_Core_WoshModule_H__

 #include <woshDefs.h>
 #include <core/Object.h>
 #include <core/Bus.h>
 #include <core/LogContext.h>
 #include <core/BusConnector.h>
 #include <core/MethodsProvider.h>
 #include <core/PropertiesProvider.h>
 #include <core/InterfacesProvider.h>
 #include <core/Settings.h>


namespace wosh {

 #define _WoshModule_NAME					"wosh.WoshModule"

 #define _WoshModule_KEY_State				"State"

#define WOSH_MODULE(CLASSNAME)		\
		WOSH_CLASSNAME(CLASSNAME)	\
		WOSH_CLASS_ABSTRACT(false)

class SecurityToken;
class WoshKernel;
template <class T> class DataFieldCollector;

class WoshModule :	public Object,
					public virtual IBusListener,
					protected virtual IPropertiesProviderListener,
					public MethodRunner
 {
	WOSH_CLASSNAME(wosh::WoshModule)
	WOSH_CLASS_ABSTRACT(true)


	protected:
		/**
		 * @brief  Default constructor. Initialize some properties and hosted methods.
		 * @param parent [in] WoshKernel singleton, passed to Object constructor
		 * @note   Called by WoshKernel or by static getter (meyer singleton)
		 */
		WoshModule( const WoshKernel* parent = NULL, const std::string& name = _WoshModule_NAME, const std::string& uri = "" );
		friend class WoshKernel;

	private:
		/// private copy constructor (object non-copiable)
		WoshModule(const WoshModule&) : Object() { }
		/// private assigment operator (object non-copiable)
		WoshModule& operator=(const WoshModule&) { return *this; }

	public:
		/**
		 * @brief  Empty destructor.
		 */
		virtual ~WoshModule() { }


/** @name Public methods
 * @{
 ******************************************************************************/
	public:
		/**
		 * @brief  Start a synchronous diagnostic procedure
		 * @return WRET_OK on success, custom error code on errors
		 */
		virtual WRESULT diagnostic();

		bool isInitialized() const			{ return (this->initState == 1); }
		bool isDeinitialized() const		{ return (this->initState == 2); }

//@}
/** @name Getters
 * @{
 ******************************************************************************/
	public:
		const InterfacesProvider& getInterfaces() const		{ return this->Interfaces; }

		static DataFieldCollector<WoshModule>* getDataFields();

//@}
/** @name Kernels Events 
 * @{
 ******************************************************************************/
	public:
		/**
		 * @brief  Event raised synchonously by the Kernel when switching to WoshKernel::STATE_INITIALIZING state
		 * @return WRET_OK on success, custom error code on errors
		 */
		virtual WRESULT onKernelInitializing();
		/**
		 * @brief  Event raised synchonously by the Kernel when switching to WoshKernel::STATE_INITIALIZED state
		 * @return WRET_OK on success, custom error code on errors
		 */
		virtual WRESULT onKernelInitialized();
		/**
		 * @brief  Event raised synchonously by the Kernel when switching to WoshKernel::STATE_RUNNING state
		 * @return WRET_OK on success, custom error code on errors
		 */
		virtual WRESULT onKernelRunning();
		/**
		 * @brief  Event raised synchonously by the Kernel when switching to WoshKernel::STATE_STOPPING state
		 * @return WRET_OK on success, custom error code on errors
		 */
		virtual WRESULT onKernelStopping();
		/**
		 * @brief  Event raised synchonously by the Kernel when switching to WoshKernel::STATE_STOPPED state
		 * @return WRET_OK on success, custom error code on errors
		 */
		virtual WRESULT onKernelStopped();

//@}
/** @name Message Events (incoming message)
 * @{
 ******************************************************************************/
	public:
		virtual void busMessage( const Message& message, const Bus* source );
//@}
/** @name IPropertiesProviderListener interface
 * @{
 ******************************************************************************/
 	protected:
		virtual inline bool readingProperty( Property* , const PropertiesProvider*  ) { return true; }
		virtual bool updatingProperty( bool& do_update, const Variant& value_proposed, Property& property_current, const PropertiesProvider* source );
		friend class wosh::PropertiesProvider;
//@}
/** @name Internal Mehods
 * @{
 ******************************************************************************/
	protected:
		/**
		 * @brief  Forward the Kernel-event to its specific (virtual) method,
		 *         which is usually overriden by(re)eimplementation.
		 * @param new_state [in] the new kernel state
		 * @param old_state [in] the old (previous) kernel state
		 * @return WRET_OK on success, custom error code on errors
		 */
		virtual WRESULT kernel_StateChanged( int new_state, int old_state );

		//virtual SecurityToken* generateCredentials() const;
		virtual SecurityToken* signMessage( Message* message ) const;

//@}
	protected:
		BusConnector BusCore;					///< connector to Core
		mutable LogContext Log;					///< my log
		mutable MethodsProvider Methods;		///< hosted methods
		mutable PropertiesProvider Properties;	///< my properties
		mutable InterfacesProvider Interfaces;	///< my interfaces
		short initState;						///< 0=created; 1=initialized 2=DE-initialized


}; // class def

}; // namespace wosh

#endif //__WOSH_Core_WoshModule_H__
